﻿using System;
using TechTalk.SpecFlow;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using ShoppingLists.Core;

namespace ShoppingLists.AcceptanceTests.Features.Steps
{
    [Binding]
    public class CreationOfAShoppingListSteps
    {
        private ShoppingListPresenter testee;
        private String shoppingListName;

        [Given(@"I have created a new empty shopping list")]
        public void GivenIHaveCreatedANewEmptyShoppingList()
        {
            testee = new ShoppingListPresenter();
            shoppingListName = "shoppinglist1";
            testee.createShoppingList(shoppingListName);
        }

        [Given(@"I have created a new empty shopping list ""(.*)""")]
        public void GivenIHaveCreatedANewEmptyShoppingList(string newShoppingListName)
        {
            testee = new ShoppingListPresenter();
            shoppingListName = newShoppingListName;
            testee.createShoppingList(shoppingListName);
        }

        [Given(@"I have an initial shopping list containing the products ""(.*)"" and ""(.*)""")]
        public void GivenIHaveAnInitialShoppingListContainingTheProductsAnd(string product1, string product2)
        {
            testee = new ShoppingListPresenter();
            shoppingListName = "shoppinglist1";
            testee.createShoppingList(shoppingListName);
            testee.addProduct(product1,shoppingListName);
            testee.addProduct(product2, shoppingListName);
        }

        [Given(@"the predefined products list is empty")]
        public void GivenThePredefinedProductsListIsEmpty()
        {
            testee = new ShoppingListPresenter();
        }

        [Given(@"the predefined products list is containing the products ""(.*)"" and ""(.*)""")]
        public void GivenThePredefinedProductsListIsContainingTheProductsAnd(string product1, string product2)
        {
            testee = new ShoppingListPresenter();
            testee.addProduct(product1);
            testee.addProduct(product2);
        }
        
        [When(@"I add a new ""(.*)"" to the shopping list")]
        public void WhenIAddANewToTheShoppingList(string product)
        {
            testee.addProduct(product, shoppingListName);
        }

        [When(@"I remove ""(.*)"" from the shopping list")]
        public void WhenIRemoveFromTheShoppingList(string product)
        {
            testee.removeProduct(product, shoppingListName);
        }

        [When(@"I add a new ""(.*)"" to the predefined products list")]
        public void WhenIAddANewToThePredefinedProductsList(string product)
        {
            testee.addProduct(product);
        }

        [When(@"I remove ""(.*)"" from the predefined products list")]
        public void WhenIRemoveFromThePredefinedProductsList(string product)
        {
            testee.removeProduct(product);
        }

        [Then(@"I have (.*) new product on the shopping list")]
        [Then(@"I have (.*) new products on the shopping list")]
        [Then(@"I have (.*) products on the shopping list")]
        public void ThenIHaveNewProductsOnTheShoppingList(int numberOfProductsInShoppingList)
        {
            Assert.AreEqual(numberOfProductsInShoppingList, testee.numberOfProducts(shoppingListName));
        }

        [Then(@"the new ""(.*)"" appears in the shopping list")]
        public void ThenTheNewAppearsInTheShoppingList(string product)
        {
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product).Any());
        }

        [Then(@"the ""(.*)"", ""(.*)"", ""(.*)"", ""(.*)"", ""(.*)"" appear in the shopping list")]
        public void ThenTheAppearInTheShoppingList(string product1, string product2, string product3, string product4, string product5)
        {
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product1).Any());
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product2).Any());
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product3).Any());
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product4).Any());
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product5).Any());
        }

        [Then(@"the ""(.*)"", ""(.*)"", ""(.*)"" remain in the shopping list")]
        public void ThenTheRemainInTheShoppingList(string product1, string product2, string product3)
        {
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product1).Any());
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product2).Any());
            Assert.True(testee.shoppingLists[shoppingListName].Products.Where(x => x.ProductName == product3).Any());
        }

        [Then(@"I have (.*) new product on the predefined products list")]
        [Then(@"I have (.*) new products on the predefined products list")]
        [Then(@"I have (.*) products on the predefined products list")]
        public void ThenIHaveNewProductOnThePredefinedProductsList(int numberOfProductsInPredefinedProductsList)
        {
            Assert.AreEqual(numberOfProductsInPredefinedProductsList, testee.numberOfProducts());
        }

        [Then(@"the new ""(.*)"" appears in the predefined products list")]
        public void ThenTheNewAppearsInThePredefinedProductsList(string product)
        {
            Assert.AreEqual(product, testee.predefinedProductsList.Products.First().ProductName);
        }

        [Then(@"the ""(.*)"", ""(.*)"", ""(.*)"", ""(.*)"", ""(.*)"" appear in the predefined products list")]
        public void ThenTheAppearInThePredefinedProductsList(string product1, string product2, string product3, string product4, string product5)
        {
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product1).Any());
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product2).Any());
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product3).Any());
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product4).Any());
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product5).Any());
        }

        [Then(@"the ""(.*)"", ""(.*)"", ""(.*)"" remain in the predefined products list")]
        public void ThenTheRemainInThePredefinedProductsList(string product1, string product2, string product3)
        {
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product1).Any());
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product2).Any());
            Assert.True(testee.predefinedProductsList.Products.Where(x => x.ProductName == product3).Any());
        }
    }
}
